package org.monitor.http;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletResponse;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.monitor.kit.FileKit;

public class DownloadClient {
	
	private String url;
	private Map<String, String> pairs;
	
	private int socketOut = 8000;
	private int connOut = 10000;
	
	private CloseableHttpClient httpClient;
	
	public DownloadClient(String url){
		this.url = url;
		this.httpClient = HttpClientBuilder.create().build();
	}
	
	public RestResult execute(String distFilename){
		RestResult rst = new RestResult();
		
		HttpRequestBase req = getRequest();
		try {
			req.setConfig(getReqConfig());
			HttpResponse resp = httpClient.execute(req);
			HttpEntity entity = resp.getEntity();
			if(HttpServletResponse.SC_OK != resp.getStatusLine().getStatusCode()){
				rst.setState(resp.getStatusLine().getStatusCode());
				rst.setMsg(EntityUtils.toString(entity));
				
			}else {
				InputStream is = null;
				FileOutputStream fos = null;
				try {
					is = entity.getContent();
					
					File distFile = getDistFile(distFilename);
					fos = new FileOutputStream(distFile);
					byte[] buffer=new byte[1024];  
					int len = 0;  
					while ((len = is.read(buffer)) != -1) {  
						fos.write(buffer, 0, len);  
					}  
					fos.flush();
					rst.setData(distFile.getPath());
				}catch(Exception e){
					rst.setState(-1);
					rst.setMsg(e.getMessage());
				}finally {
					FileKit.close(is);
					FileKit.close(fos);
				}
			}
			
		} catch (Exception e) {
			rst.setState(-1);
			rst.setMsg(e.getMessage());
		}finally {
			FileKit.close(httpClient);
		}
		return rst;
	}
	
	private File getDistFile(String distFilename) throws IOException {
		File distFile = new File(distFilename);
		if(distFile.exists()){
			distFile.delete();
		}
		distFile.getParentFile().mkdirs();
		distFile.createNewFile();
		return distFile;
	}

	protected RequestConfig getReqConfig() {
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketOut).setConnectTimeout(connOut).build();//设置请求和传输超时时间
		return requestConfig;
	}

	private HttpRequestBase getRequest(){
		return getGetReq();
	}
	
	protected HttpRequestBase getGetReq(){
		HttpRequestBase req = new HttpGet(getUrlWithPairs());
		return req;
	}
	
	private String getUrlWithPairs(){
		String urlWithParams = this.url;
		if(this.pairs != null && this.pairs.size() > 0){
			StringBuffer sb = new StringBuffer(this.url);
			if(sb.indexOf("?") > 0) {
				sb.append("&");
			}else {
				sb.append("?");
			}
			for (Entry<String, String> entry : pairs.entrySet()) {
				String name = entry.getKey();
				String value = entry.getValue();
				sb.append(name).append("=").append(value).append("&");
			}
			urlWithParams = sb.toString();
		}
		return urlWithParams;
	}

	public void setPairs(Map<String, String> pairs) {
		this.pairs = pairs;
	}
	
	public void addPair(String name, String value){
		if(this.pairs == null){
			this.pairs = new HashMap<String, String>();
		}
		if(name != null && value != null){
			this.pairs.put(name, value);
		}
	}
	
	public void setSocketTimeout(int socketOut){
		this.socketOut = socketOut;
	}
	
	public void setConnectTimeout(int connOut){
		this.connOut = connOut;
	}
	
}
